package com.icloud.common.web.util;

import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.icloud.common.web.vo.IpAddressVo;
import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.exception.GeoIp2Exception;
import com.maxmind.geoip2.model.CountryResponse;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.ip2region.core.Ip2regionSearcher;
import net.dreamlu.mica.ip2region.core.IpInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;

/**
 * IP相关公共工具
 */
@Slf4j
@Component
public class IpUtil {
    private static Ip2regionSearcher ip2regionSearcher;

    @Autowired
    public IpUtil (Ip2regionSearcher ip2regionSearcher) {
        IpUtil.ip2regionSearcher = ip2regionSearcher;
    }

    /**
     * 获取HttpServletRequest实例
     */
    public static HttpServletRequest getRequest() {
        if(RequestContextHolder.getRequestAttributes() == null) {
            return null;
        }
        return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
    }

    /**
     * 获取用户的真实地址
     */
    public static String getIpAddr() {
        IpAddressVo vo = getIpAndAddress();
        if(vo == null) {
            return "";
        }else {
            return vo.getIp();
        }
    }

    /**
     * 根据ip获取地址信息
     */
    public static String getAddressInfoByIp(String ip) {
        IpInfo ipInfo = ip2regionSearcher.memorySearch(ip);
        if(ipInfo == null) {
            log.error("获取IpInfo对象失败");
            return "";
        }
        //返回完整的地址，附带运营商
        return ipInfo.getAddressAndIsp();
    }

    /**
     * 获取用户的真实IP和地址信息
     */
    public static IpAddressVo getIpAndAddress() {
        HttpServletRequest request = getRequest();
        if(request == null) {
            return null;
        }
        IpAddressVo vo = new IpAddressVo();
        //从cf-connecting-ip中获取真实IP
        String ip = request.getHeader("cf-connecting-ip");
        if(null != ip) {
            vo.setIp(ip);
            String address = request.getHeader("cf-ipcountry");
            vo.setAddress(null != address ? address : "");
        }else {
            ip = request.getHeader("x-forwarded-for");
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
            if(ip.contains(",")) {
                //多个路由时，取第一个非unknown的ip
                String[] ipArr = ip.split(",");
                ip = ipArr[0].trim();
            }
            if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
                //获取本机真正的ip地址
                try {
                    ip = InetAddress.getLocalHost().getHostAddress();
                } catch (UnknownHostException e) {
                    log.error("获取ip地址失败：{}", e.getMessage());
                    ip = "";
                }
            }
            vo.setIp(ip);
            vo.setAddress(getAddressInfoByIp(ip));
        }
        return vo;
    }

    /**
     * 获取浏览器登录类型
     */
    public static String getUserAgent() {
        HttpServletRequest request = getRequest();
        if(request == null) {
            return "";
        }
        String browser = request.getHeader("user-agent");
        UserAgent userAgent = UserAgentUtil.parse(browser);
        String browserType = userAgent.getBrowser().toString(); //Chrome
        String version = userAgent.getVersion(); //14.0.835.163
        String engine = userAgent.getEngine().toString(); //Webkit
        String engineVersion = userAgent.getEngineVersion(); //535.1
        String os = userAgent.getOs().toString(); //Windows 7
        String platform = userAgent.getPlatform().toString(); //Windows
        Integer mobile = userAgent.isMobile() ? 1 : 0;
        return browserType;
    }

    /**
     * 获取使用平台
     */
    public static String getUserPlatform() {
        HttpServletRequest request = getRequest();
        if(request == null) {
            return "";
        }
        String browser = request.getHeader("user-agent");
        UserAgent userAgent = UserAgentUtil.parse(browser);
        String browserType = userAgent.getBrowser().toString(); //Chrome
        String version = userAgent.getVersion(); //14.0.835.163
        String engine = userAgent.getEngine().toString(); //Webkit
        String engineVersion = userAgent.getEngineVersion(); //535.1
        String os = userAgent.getOs().toString(); //Windows 7
        String platform = userAgent.getPlatform().toString(); //Windows
        System.out.println("os信息：  "+os);
        System.out.println("platform信息：  "+platform);
        if(platform.toLowerCase().contains("android")) {
            platform = "Android";
        } else if(platform.toLowerCase().contains("iphone")) {
            platform = "IOS";
        }else{
            platform = "WEB";
        }

        return platform;
    }

    /**
     * 根据IP获取国家信息
     */
    public static String getCountryNameByIp(String ip) {
        String countryName = "";
        try {
            //使用GeoIp数据库匹配 匹配未成功，调用第三方
            ClassPathResource classPathResource = new ClassPathResource("data/" + "GeoLite2-Country.mmdb");
            InputStream inputStream = classPathResource.getInputStream();
            byte[] bytes = FileCopyUtils.copyToByteArray(inputStream);
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
            DatabaseReader.Builder builder = new DatabaseReader.Builder(byteArrayInputStream);
            DatabaseReader reader = builder.build();
            CountryResponse country = reader.country(InetAddress.getByName(ip));

            if (country != null) {
                countryName= reader.country(InetAddress.getByName(ip)).getCountry().getName();
            } else {
                //创建Url类
                URL url = new URL("http://ip-api.com/json/" + ip);
                //创建HttpURLConnection类，由这个类发起Http请求
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                //设置请求参数
                httpURLConnection.setRequestMethod("GET");
                httpURLConnection.setDoOutput(true);
                //发起请求建立链接
                InputStream inputStream1 = httpURLConnection.getInputStream();
                //读取response的返回值
                ByteArrayOutputStream bout = new ByteArrayOutputStream();
                byte[] bytes1 = new byte[1024];
                int len = 0;
                while ((len = inputStream1.read(bytes1)) >= 0) {
                    bout.write(bytes1, 0, len);
                }
                inputStream1.close();
                bout.close();
                String respone = bout.toString();
                JSONObject jsonObject = JSON.parseObject(respone);
                countryName = jsonObject.getString("country");
            }
            return countryName;
        }catch (IOException | GeoIp2Exception ignore) {
            log.error("根据IP获取国家信息异常，The address not in the databaes");
        }
        return countryName;
    }
}
